local AddOnName, Env = ...; local ADDON, DEV = Env[1], Env[1].DEV
-- ~~| Libraries |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local AceConfigRegistry	= LibStub("AceConfigRegistry-3.0")
local DiesalStyle 		= LibStub("DiesalStyle-1.0")
local DiesalGUI 			= LibStub("DiesalGUI-1.0")
local DiesalMenu 			= LibStub('DiesalMenu-1.0')
-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local pairs, ipairs							= pairs,ipairs
local type	 									= type
local gsub, sub, find, format 			= string.gsub, string.sub, string.find, string.format
local concat									= table.concat
-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~| RotationSelecter |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ADDON.RotationConfigs = {}
ADDON.Rotations = {}
for i = 1, 6 do ADDON.Rotations[i] = {} end
-- ~~| RotationSelecter StyleSheets |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

local dividerStyleSheet = {	
	['top'] = {
		type			= 'texture',
		layer			= 'ARTWORK',		
		color			= 'ffffff',
		alpha			= .04,	
		offset		= {-1,-1,-1,nil},	
		height		= 1,
	},
	['black'] = {
		type			= 'texture',
		layer			= 'ARTWORK',		
		color			= '000000',	
		offset		= {0,0,-2,nil},	
		height		= 1,
	},
	['bottom'] = {
		type			= 'texture',
		layer			= 'ARTWORK',		
		color			= 'ffffff',
		alpha			= .04,	
		offset		= {-1,-1,-3,nil},	
		height		= 1,
	},		
}
local inputStyleSheet = {	
		['background'] = {	
			type			= 'texture',
			layer			= 'BACKGROUND',
			color			= '000000',
			offset		= 0,		
		},
		['gradient'] = {			
			type			= 'texture',
			layer			= 'BORDER',
			gradient		= 'VERTICAL',							
			color			= 'ffffff',	
			alpha 		= 0,
			alphaEnd		= .1,
			offset		= -1,		
		},
		['outline'] = {		
			type			= 'outline',
			layer			= 'BORDER',	
			color			= '000000',
			offset		= 0,		
		},	
		['inline'] = {		
			type			= 'outline',
			layer			= 'BORDER',
			gradient		= 'VERTICAL',	
			color			= 'ffffff',
			alpha 		= .04,
			alphaEnd		= .10,
			offset		= -1,	
		},	
		['hover'] = {		
			type			= 'outline',
			layer			= 'HIGHLIGHT',
			color			= 'ffffff',
			alpha 		= .12,	
			offset		= -1,	
		},		
	}
-- ~~| RotationSelecter Colors |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local GREY75		= ADDON:GetTxtColor('c0c0c0')
local GREY50		= ADDON:GetTxtColor('808080')
local BLUE			= ADDON:GetTxtColor('0099e6')	
local ORANGE		= ADDON:GetTxtColor('e6c000') 
local PURPLE		= ADDON:GetTxtColor('9900e5') 
local RED			= ADDON:GetTxtColor('ff0000') 
local YELLOW		= ADDON:GetTxtColor('ffff00')
-- ~~| RotationSelecter Locals |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--  Friendly, Neutral, Enemies, Players, FriendlyPlayers, EnemyPlayers, Rares, Objects, Moving, Attackable, and Chests.
local trackers = {
	{ id = 'EnemyPlayers', 		name = 'Enemy Players' },
	{ id = 'FriendlyPlayers', 	name = 'Friendly Players' },
	{ id = 'Enemies', 			name = 'Enemies' },
	{ id = 'Friendly', 			name = 'Friendly' },
	{ id = 'Neutral', 			name = 'Neutral' },
	{ id = 'Attackable', 		name = 'Attackable' },
	{ id = 'Objects', 			name = 'Objects' },
	{ id = 'Chests', 				name = 'Chests' },
	{ id = 'Rares', 				name = 'Rares' },
	{ id = 'Moving', 				name = 'Moving' }, 		 		
}

-- ~~| RotationSelecter Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
local methods = {		
	['Update'] = function(self)
		-- ~~ Update Position ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		self.frame:ClearAllPoints()
		if self.db.top and self.db.left then
			self.frame:SetPoint("TOP",UIParent,"BOTTOM",0,self.db.top)
			self.frame:SetPoint("LEFT",UIParent,"LEFT",self.db.left,0)
		else
			self.frame:SetPoint("CENTER",UIParent,"CENTER")
		end		
		
		for i = 1, #trackers do
			self[trackers[i].id].checkBox:SetChecked(self.db[trackers[i].id])
			if FireHack then SetTrackingState(trackers[i].id, self.db[trackers[i].id]) end
		end		
		self.frame[self.db.show and "Show" or "Hide"](self.frame)		
	end,
	['OnFireHack'] = function(self)
		for i = 1, #trackers do			
			SetTrackingState(trackers[i].id, self.db[trackers[i].id])
			if not ADDON.MenuData.Tracker.menuData then ADDON.MenuData.Tracker.menuData = {} end
			ADDON.MenuData.Tracker.menuData[trackers[i].id] = {					
				name = trackers[i].name,
				order = i,
				onClick = function()
					self.db[trackers[i].id] = not self.db[trackers[i].id]
					self[trackers[i].id].checkBox:SetChecked(self.db[trackers[i].id])	
					SetTrackingState(trackers[i].id, self.db[trackers[i].id])					
				end,
				check	= function()
					return self.db[trackers[i].id]
				end,				
			}				
		end
		self:Enable()
	end,	
	['Enable'] = function(self)
		for i = 1, #trackers do
			self[trackers[i].id].checkBox:Enable()
			self[trackers[i].id].name:SetAlpha(.7)
		end
		self.partialText:SetAlpha(.7)
		self.partialInput:EnableMouse(true)
		self.nameText:SetAlpha(.7)
		self.nameInput:EnableMouse(true)
	end,
	['Disable'] = function(self)
		for i = 1, #trackers do
			self[trackers[i].id].checkBox:Disable()
			self[trackers[i].id].name:SetAlpha(.3)
		end
		self.partialText:SetAlpha(.3)
		self.partialInput:EnableMouse(false)		
		self.nameText:SetAlpha(.3)
		self.nameInput:EnableMouse(false)
	end,	
	['Show'] = function(self)
		self.frame:Show()
	end,
	['Hide'] = function(self)
		self.frame:Hide()
	end,
}
-- ~~| RotationSelecter Constructor |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function ADDON:constructTracker()
	local self = {}
	self.db = ADDON.db.profile.tracker
	-- ~~ Default Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	local settings = {
		
	}
	settings = settings
	-- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	local window = DiesalGUI:Create('Window')
	-- window:ReleaseTextures()
	-- window:AddStyleSheet(windowStyleSheet)
	window:SetSettings({
		top				= self.db.top,
		left				= self.db.left,			
		height	 		= 156,
		width				= 202,		
		sizerR			= false,
		sizerB			= false,
		sizerBR			= false,
	},true)
	window:SetTitle(RED..AddOnName,GREY75..'Tracker')	
	window:SetEventListener('OnDragStop', function(this,event,left,top)
		self.db.left 	= left
		self.db.top 	= top
	end)
	window:SetEventListener('OnClose', function(this,event)
		self.db.show = false
		AceConfigRegistry:NotifyChange(AddOnName)
	end) 	
 	
 	for i = 1, #trackers do  		
 		local frame = CreateFrame('Frame',nil,window.content)
	 	frame:SetSize(94,12)
	 	if math.fmod(i,2) == 1 then		
	 		frame:SetPoint('TOPLEFT',4, 10 + (math.ceil(i/2)*-16))	
	 	else 
	 		frame:SetPoint('TOPLEFT',102, 10 + (i/2)*-16)
	 	end
	 	local checkBox = DiesalGUI:Create('CheckBox')
		checkBox:SetParent(frame)	
		checkBox:SetPoint("TOPLEFT")	
		checkBox:SetEventListener('OnValueChanged', function(this,event,value)
			self.db[trackers[i].id] = value
			SetTrackingState(trackers[i].id, value)			
		end)	
		checkBox:Disable()					
		local name = frame:CreateFontString(nil,"OVERLAY",'DiesalFontNormal')
		name:SetAlpha(.5)	 	
	 	name:SetPoint("TOPLEFT",14, -1)
		name:SetPoint("RIGHT")
		name:SetJustifyH("LEFT")		
		name:SetJustifyV("TOP")
		name:SetWordWrap(false)
		name:SetText(trackers[i].name)		
		
		frame.checkBox = checkBox
	 	frame.name = name
	 	self[trackers[i].id] = frame	 	
 	end
 		
 	local divider = CreateFrame('Frame',nil,window.content)
 	divider:SetHeight(3)
	divider:SetPoint('TOPLEFT',0,-86)	
 	divider:SetPoint('RIGHT',0,0)
 	DiesalStyle:AddFrameStyleSheet(divider,dividerStyleSheet)
 	
 	local nameFrame = CreateFrame('Frame',nil,window.content)
 	nameFrame:SetHeight(16)
 	nameFrame:SetPoint('TOPLEFT',divider,'BOTTOMLEFT',4,-6)	
 	nameFrame:SetPoint('TOPRIGHT',divider,'BOTTOMRIGHT',-6,-6) 						
	local nameText = nameFrame:CreateFontString(nil,"OVERLAY",'DiesalFontNormal')
	nameText:SetAlpha(.3)	 	
 	nameText:SetPoint("TOPLEFT",0, -4)
	nameText:SetPoint("RIGHT")
	nameText:SetJustifyH("LEFT")		
	nameText:SetJustifyV("TOP")
	nameText:SetWordWrap(false)
	nameText:SetText('Name')	
	local nameInput = window:CreateRegion("EditBox", 'nameFrame', nameFrame)	
	nameInput:SetHeight(16)	
	nameInput:SetPoint('TOPLEFT',37,0)
	nameInput:SetPoint('RIGHT',0,0)	
	nameInput:SetAutoFocus(false)
	nameInput:EnableMouse(false)		
	nameInput:SetJustifyH("CENTER")
	nameInput:SetJustifyV("CENTER")	
	nameInput:SetTextInsets(1,0,2,0)
	nameInput:SetTextColor(.8,.8,.8,1)		
	nameInput:SetScript('OnEnterPressed',  function(this,...)				
		TrackByName(this:GetText())
		this:SetText('')			
		DiesalGUI:ClearFocus()		
	end)
	nameInput:SetScript("OnEnter",function(this,...)		
		if not self.db.tooltips then return end
		GameTooltip:SetOwner(nameInput, "ANCHOR_TOPRIGHT",0,2)
		GameTooltip:AddLine('Track objects with this name.',nil,nil,nil,1)
		GameTooltip:Show()		
	end)
	nameInput:SetScript("OnLeave", function(this,...)		
		GameTooltip:Hide()				
	end)			
	DiesalStyle:AddFrameStyleSheet(nameInput,inputStyleSheet)
	
 	local partialFrame = CreateFrame('Frame',nil,window.content)
 	partialFrame:SetHeight(16)
 	partialFrame:SetPoint('TOPLEFT',nameFrame,'BOTTOMLEFT',0,-4)	
 	partialFrame:SetPoint('TOPRIGHT',nameFrame,'BOTTOMRIGHT',0,-4) 						
	local partialText = partialFrame:CreateFontString(nil,"OVERLAY",'DiesalFontNormal')
	partialText:SetAlpha(.3)	 	
 	partialText:SetPoint("TOPLEFT",0, -4)
	partialText:SetPoint("RIGHT")
	partialText:SetJustifyH("LEFT")		
	partialText:SetJustifyV("TOP")
	partialText:SetWordWrap(false)
	partialText:SetText('Partial')	
	local partialInput = window:CreateRegion("EditBox", 'partialFrame', partialFrame)	
	partialInput:SetHeight(16)	
	partialInput:SetPoint('TOPLEFT',37,0)
	partialInput:SetPoint('RIGHT',0,0)	
	partialInput:SetAutoFocus(false)	
	partialInput:EnableMouse(false)		
	partialInput:SetJustifyH("CENTER")
	partialInput:SetJustifyV("CENTER")	
	partialInput:SetTextInsets(1,0,2,0)
	partialInput:SetTextColor(.8,.8,.8,1)
	partialInput:SetAltArrowKeyMode(true)	
	partialInput:SetHistoryLines(10)	
	partialInput:HookScript('OnEnterPressed',  function(this,...)				
		TrackPartial(this:GetText())
		this:AddHistoryLine(this:GetText())
		this:SetText('')			
		DiesalGUI:ClearFocus()		
	end)	
	partialInput:HookScript('OnEscapePressed',  function(this,...)		
		this:SetText('')			
		DiesalGUI:ClearFocus()		
	end)	
	partialInput:HookScript("OnEnter",function(this,...)		
		if not self.db.tooltips then return end
		GameTooltip:SetOwner(partialInput, "ANCHOR_TOPRIGHT",0,2)
		GameTooltip:AddLine('Track objects whose name contain this name.',nil,nil,nil,1)
		GameTooltip:Show()		
	end)
	partialInput:HookScript("OnLeave", function(this,...)		
		GameTooltip:Hide()				
	end)			
	DiesalStyle:AddFrameStyleSheet(partialInput,inputStyleSheet)
 		
	-- ~~ Frames ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	self.window 				= window
	self.frame 					= window.frame	
	
	self.nameText 				= nameText
	self.nameInput 			= nameInput
	self.partialText 			= partialText
	self.partialInput 		= partialInput
	-- ~~ Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	for method, func in pairs(methods) do
		self[method] = func
	end	
	-- ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	self:Hide()
	return self
end